package com.sensor.meter.utils

import android.annotation.SuppressLint
import android.media.AudioFormat
import android.media.AudioRecord
import android.media.MediaRecorder
import org.jetbrains.annotations.NotNull
import java.util.concurrent.Executors
import kotlin.math.log10

/**
 * @author       CT
 * @date         2024/3/11
 * @description  录音工具
 */
class AudioRecordUtil(@NotNull val soundRecordCallback:SoundRecordCallback) {

  // 采样值
  private val SAMPLE_RATE_IN_HZ = 8000
  private val CHANNEL =   AudioFormat.CHANNEL_IN_DEFAULT/*CHANNEL_IN_MONO*/
  private val FORMAT = AudioFormat.ENCODING_PCM_16BIT
  private val MIN_BUFFER_SIZE = AudioRecord.getMinBufferSize(SAMPLE_RATE_IN_HZ, CHANNEL, FORMAT)
  private var isStarted = false
  private lateinit var audioRecord: AudioRecord

  private val mLock= Object()

  private fun openAudio(){
    // 创建 2 个线程的线程池
    // 创建 2 个线程的线程池
    val threadPool = Executors.newFixedThreadPool(2)
    threadPool.submit(Runnable {
      audioRecord.startRecording()
      val buffer = ShortArray(MIN_BUFFER_SIZE)
      while (isStarted) {
        //r是实际读取的数据长度，一般而言r会小于buffersize
        val r: Int = audioRecord.read(buffer, 0, MIN_BUFFER_SIZE)
        var v: Long = 0
        // 将 buffer 内容取出，进行平方和运算
        for (i in buffer.indices) {
          v += (buffer[i] * buffer[i]).toLong()
        }
        // 平方和除以数据总长度，得到音量大小。
        val mean = v / r.toDouble()
        val volume = 10 * log10(mean)
        LogUtil.d("SoundMeter:{$volume} db")
        // 回调
        soundRecordCallback!!.callback(volume)
        // 大概一秒十次
        synchronized(mLock) {
          try {
            mLock.wait(100)
          } catch (e: InterruptedException) {
            e.printStackTrace()
          }
        }
      }
      audioRecord.stop()
      audioRecord.release()
    })
  }

  @SuppressLint("MissingPermission")
  open fun start() {
    if(isStarted){
      return
    }
    audioRecord = AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE_IN_HZ, CHANNEL, FORMAT, MIN_BUFFER_SIZE)
    isStarted = true
    openAudio()
  }

  open fun stop() {
    audioRecord.stop()
    isStarted = false
  }

  fun restart() {
    stop()
    start()
  }

  fun getIsStarted(): Boolean {
    return isStarted
  }

  open fun interface SoundRecordCallback{
    /**
     * 分贝回调值
     * @param volume Double
     */
    fun callback(volume:Double)
  }

}